home *** CD-ROM | disk | FTP | other *** search
- ; GUS lowlevel interface.
-
- .386p
- code32 segment para public use32
- assume cs:code32, ds:code32
-
- include pmode.inc
-
- public _gusrout, _gusport, _gusirq, _gusram
- public _vccmnd, _vccntrl, _vcsbeg, _vclbeg, _vclend, _vcfreq, _vcpan, _vcvol
- public _gustimerfreq, _gusnumvoices
-
- public _gs_init, _gs_uninit, _gs_putram, _gs_getram
-
- ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
- ; DATA
- ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
- align 4
- EXTRACRAP = 1 ; 0=no extras, 1=yes extras
-
- aclbeg dd 32 dup(?) ; actual channel loop begin |
- aclend dd 32 dup(?) ; actual channel loop end |
- acfreq dw 32 dup(?) ; actual channel frequency value |
- acpan db 32 dup(?) ; actual channel pan position |
- acvol db 32 dup(?) ; actual channel volume (high byte) |
- ; |
- _vccmnd db 16 dup(?) ; virtual channel command bits |
- ; bit 0: volume change
- ; bit 1: balance change
- ; bit 2: frequency change
- ; bit 3: sample note-on
- _vccntrl db 16 dup(?) ; virtual channel voice control
- ; bit 3: enable loop
- ; bit 4: bi-directional loop
- ; bit 6: 0=forward, 1=reverse
- _vcsbeg dd 16 dup(?) ; virtual channel sample begin
- _vclbeg dd 16 dup(?) ; virtual channel loop begin
- _vclend dd 16 dup(?) ; virtual channel loop end
- _vcfreq dw 16 dup(?) ; virtual channel frequency value
- _vcpan db 16 dup(?) ; virtual channel pan position
- _vcvol db 16 dup(?) ; virtual channel volume (high byte)
-
- vcacoff db 16 dup(0) ; virtual channel offset in actual
-
- ormgusirqvect dd ? ; old real mode GF1 IRQ vector
-
- gusport102 dw ? ; GUS port + 102h
- gusport103 dw ? ; GUS port + 103h
- gusport104 dw ? ; GUS port + 104h
- gusport107 dw ? ; GUS port + 107h
-
- _gusrout dd _ret ; routine to call on every timer tick
- _gusport dw 220h
- _gusirq db 11
- _gusram db 0 ; 1=256k, 2=512k, 3=768k, 4=1024k
- _gustimerfreq db 0cch ; =256-((1000000/Hz)/320)
- _gusnumvoices db 0dfh ; =((Voices*2)-1)|0xc0
-
- rmgusirqbuf db 21 dup(?) ; buffer for rm GF1 IRQ callback code
-
- port103val db 43h ; value to set on exit from IRQ
- irqm0tbl dw 0c089h,0a0e6h
- gusirqvaltbl db 0,0,41h,43h,0,42h,0,44h,0,0,0,45h,46h,0,0,47h
- ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
- ; CODE
- ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
-
- ;-----------------------------------------------------------------------------
- @gusoutb macro index,value
- mov al,&index
- out dx,al
- add dl,2
- mov al,&value
- out dx,al
- sub dl,2
- endm
-
- @gusoutw macro index,value
- mov al,&index
- out dx,al
- inc edx
- mov ax,&value
- out dx,ax
- dec edx
- endm
-
- ;═════════════════════════════════════════════════════════════════════════════
- ; GUS timer IRQ entry
- irq:
- push eax
- mov al,20h
- out 20h,al
- irqm0 dw ? ; out 0a0h,al | mov eax,eax
- sti
- cld
- push ebx ecx edx esi edi ebp ds
- mov ds,cs:_seldata
- mov dx,gusport103 ; reenable GUS timer
- @outb 45h
- add dl,2
- @outb 0
- @outb 8
-
- call _gusrout
-
- ;-----------------------------------------------------------------------------
- mov dx,gusport103
- mov ebp,15
- irql0:
- xor cl,cl
- xchg cl,_vccmnd[ebp]
- or cl,cl
- jz irql0c
-
- movzx edi,vcacoff[ebp]
- lea edi,[ebp*2+edi]
-
- test cl,8
- jz short irql0f0
- xor vcacoff[ebp],1
- mov eax,edi
- dec edx
- out dx,al
- inc edx
- mov bl,acvol[edi]
- @gusoutb 7,4
- @gusoutb 8,bl
- @gusoutb 9,bl
- @gusoutb 0dh,40h
- xor edi,1
- or cl,7
- irql0f0:
-
- mov eax,edi
- dec edx
- out dx,al
- inc edx
-
- test cl,4
- jz short irql0f1
- mov bx,_vcfreq[ebp*2]
- cmp bx,acfreq[edi*2]
- je short irql0f1
- mov acfreq[edi*2],bx
- @gusoutw 1,bx
- irql0f1:
-
- test cl,2
- jz short irql0f2
- mov bl,_vcpan[ebp]
- cmp bl,acpan[edi]
- je short irql0f2
- mov acpan[edi],bl
- @gusoutb 0ch,bl
- irql0f2:
-
- test cl,8
- jz irql0f3
- mov esi,_vclbeg[ebp*4]
- cmp esi,aclbeg[edi*4]
- je short irql0f2f0
- mov aclbeg[edi*4],esi
- shrd bx,si,7
- shr esi,7
- @gusoutw 2,si
- @gusoutb 3,bh
- irql0f2f0:
- mov esi,_vclend[ebp*4]
- cmp esi,aclend[edi*4]
- je short irql0f2f1
- mov aclend[edi*4],esi
- shrd bx,si,7
- shr esi,7
- @gusoutw 4,si
- @gusoutb 5,bh
- irql0f2f1:
- mov esi,_vcsbeg[ebp*4]
- shrd bx,si,7
- shr esi,7
- @gusoutw 0ah,si
- @gusoutb 0bh,bh
- @gusoutb 0,_vccntrl[ebp]
- irql0f3:
-
- test cl,1
- jz short irql0f4
- mov bl,_vcvol[ebp]
- mov bh,acvol[edi]
- mov ah,bh
- cmp bh,bl
- je short irql0f4
- mov ch,40h
- ja short irql0f3f0
- xchg bl,bh
- xor ch,ch
- irql0f3f0:
- @gusoutb 7,bl
- @gusoutb 8,bh
- @gusoutb 9,ah
- @gusoutb 0dh,ch
- irql0f4:
-
- mov dx,300h
- db 7 dup(0ech) ; in al,dx
- mov dx,gusport103
-
- test cl,1
- jz short irql0f5
- mov al,_vcvol[ebp]
- cmp al,ah
- je short irql0f5
- mov acvol[edi],al
- @gusoutb 9,ah
- @gusoutb 0dh,ch
- irql0f5:
-
- test cl,8
- jz short irql0c
- mov esi,_vcsbeg[ebp*4]
- shrd bx,si,7
- shr esi,7
- @gusoutw 0ah,si
- @gusoutb 0bh,bh
- @gusoutb 0,_vccntrl[ebp]
- xor edi,1
- mov eax,edi
- dec edx
- out dx,al
- inc edx
- mov bl,4
- xchg bl,acvol[edi]
- @gusoutb 9,bl
- @gusoutb 0dh,40h
-
- irql0c:
- sub ebp,1
- jnc irql0
-
- @outb port103val
-
- ;─────────────────────────────────────────────────────────────────────────────
- irqdone:
- pop ds ebp edi esi edx ecx ebx eax
- iretd
-
- ;─────────────────────────────────────────────────────────────────────────────
- ; A small delay, In: ECX - number of times to do delay
- gusdelay:
- push ax dx
- mov dx,300h
- gusdelayl0:
- in al,dx
- in al,dx
- in al,dx
- in al,dx
- in al,dx
- in al,dx
- in al,dx
- loop gusdelayl0
- pop dx ax
- ret
-
- ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
- ; Shove some crap into GUS ram
- ; In:
- ; EBX - addx in GUS ram to shove into
- ; ECX - amount of crap to shove
- ; EDX -> actual crap to shove
- ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
- _gs_putram:
- push eax ebx ecx dx esi
- mov esi,edx
- mov dx,gusport104
- gsputraml0:
- dec edx
- mov al,44h
- mov port103val,al
- out dx,al
- add dl,2
- shld eax,ebx,16
- out dx,al
- sub dl,2
- mov al,43h
- mov port103val,al
- out dx,al
- inc edx
- gsputraml1:
- mov ax,bx
- out dx,ax
- add dl,3
- outsb
- sub dl,3
- inc bx
- loopnz gsputraml1
- jecxz short gsputramd
- add ebx,10000h
- jmp gsputraml0
- gsputramd:
- pop esi dx ecx ebx eax
- ret
-
- ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
- ; Rip some crap outta GUS ram
- ; In:
- ; EBX - addx in GUS ram to rip from
- ; ECX - amount of crap to rip
- ; EDX -> buffer for ripped crap
- ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
- _gs_getram:
- push eax ebx ecx dx edi
- mov edi,edx
- mov dx,gusport104
- gsgetraml0:
- dec edx
- mov al,44h
- mov port103val,al
- out dx,al
- add dl,2
- shld eax,ebx,16
- out dx,al
- sub dl,2
- mov al,43h
- mov port103val,al
- out dx,al
- inc edx
- gsgetraml1:
- mov ax,bx
- out dx,ax
- add dl,3
- insb
- sub dl,3
- inc bx
- loopnz gsgetraml1
- jecxz short gsgetramd
- add ebx,10000h
- jmp gsgetraml0
- gsgetramd:
- pop edi dx ecx ebx eax
- ret
-
- ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
- ; Initialize GUS sound system
- ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
- _gs_init:
- pushad
- mov ax,900h
- int 31h
- push ax
-
- mov dx,_gusport ; set up all port vars
- @outb 0bh
- add dx,102h
- mov gusport102,dx
- inc edx
- mov gusport103,dx
- inc edx
- mov gusport104,dx
- add dl,3
- mov gusport107,dx
-
- sub dl,4 ; initialize GUS
- @outb 4ch
- add dl,2
- @outb 0
- mov ecx,10h
- call gusdelay
- @outb 1
- sub dl,2
- mov ecx,10h
- call gusdelay
- @gusoutb 41h,0
- @gusoutb 45h,0
- @gusoutb 49h,0
- @outb 0eh
- add dl,2
- @outb _gusnumvoices
- sub dl,3
-
- mov bl,1fh ; set up all voices
- gsinitl0:
- mov al,bl
- and al,7fh
- out dx,al
- inc edx
- @gusoutw 9,0
- @gusoutb 0,0
- @gusoutb 0dh,3
- @gusoutb 6,16
- @outb 0ch
- add dl,2
- @outb 7
- sub dl,3
- mov ecx,1
- call gusdelay
- xor bl,80h
- js gsinitl0
- sub bl,1
- jnc gsinitl0
-
- sub dx,0f3h ; damn, another undocumented port
- @outb 5
- sub dl,0fh
- @outb 8
- add dl,0bh
- xor al,al
- out dx,al
- add dl,4
- out dx,al
- sub dl,0fh
-
- movzx ebx,_gusirq ; set IRQ channels
- @outb 4bh
- add dl,0bh
- mov al,gusirqvaltbl[ebx]
- out dx,al
- sub dl,0bh
- @outb 9
- add dx,103h
-
- @outb 43h ; how much RAM on the card
- inc edx
- @outw 0ffffh
- dec edx
- @outb 44h
- add dl,2
- mov cl,3
- gsinitl1:
- @outb cl
- add dl,2
- in al,dx
- inc eax
- mov ah,al
- out dx,al
- in al,dx
- sub dl,2
- cmp al,ah
- jne short gsinitl1d
- inc _gusram
- add cl,4
- test cl,10h
- jz gsinitl1
- gsinitl1d:
- sub dl,2
-
- mov edi,offset aclbeg ; set some beginning values
- mov ecx,80
- mov eax,0ffffffffh
- rep stosd
- mov eax,7070707h
- mov cl,8
- rep stosd
- xor eax,eax
- mov cl,12
- rep stosd
-
- @gusoutb 4ch,3 ; enable GUS normal operation
-
- @gusoutb 47h,_gustimerfreq ; start GUS timer
- @outb 45h
- add dl,2
- @outb 8
- sub dx,0fdh
- @outb 4
- inc edx
- @outb 2
-
- cmp bl,2 ; set and enable GF1 IRQ (BL=IRQ num)
- jne short $+4
- mov bl,9
- cmp bl,7
- seta al
- movzx eax,al
- mov ax,irqm0tbl[eax*2]
- mov irqm0,ax
- mov edx,offset irq
- call _setirqvect
- xor al,al
- call _setirqmask
- mov edi,offset rmgusirqbuf
- call _rmpmirqset
- mov ormgusirqvect,edx
-
- pop ax
- int 31h
- popad
- ret
-
- ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
- ; Uninitialize GUS sound system
- ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
- _gs_uninit:
- push ax bx edx
- mov ax,900h
- int 31h
- push ax
-
- mov bl,_gusirq ; Kill GUS IRQ handler
- cmp bl,2
- jne short $+4
- mov bl,9
- mov edx,ormgusirqvect
- call _rmpmirqfree
- mov al,1
- call _setirqmask
-
- mov dx,gusport103 ; Shut down GUS
- @outb 4ch
- add dl,2
- @outb 0
- sub dx,105h
- @outb 0bh
-
- pop ax
- int 31h
- pop edx bx ax
- ret
-
- if EXTRACRAP ne 0
- ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
- ; EXTRA CRAP
- ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
-
- include kb.inc
-
- extrn _putdosmsg:near
-
- public _gs_find, _gs_ask, _gs_test
-
- ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
- ; EXTRA CRAP DATA
- ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
- pspultrastr db 'ULTRASND'
-
- askmsg0 db 'Where''s the Ultrasound bub...?',0dh,0ah
- db ' 0) I aint got one.',0dh,0ah
- db ' 1) 210h.',0dh,0ah
- db ' 2) 220h.',0dh,0ah
- db ' 3) 230h.',0dh,0ah
- db ' 4) 240h.',0dh,0ah
- db ' 5) 250h.',0dh,0ah
- db ' 6) 260h.',0dh,0ah
- db 'ENTER) 220h and 11 (default).',0dh,0ah,'$'
- askmsg1 db 0dh,0ah,'And what''s the magic IRQ number...?',0dh,0ah
- db ' 0) 2',0dh,0ah
- db ' 1) 3',0dh,0ah
- db ' 2) 5',0dh,0ah
- db ' 3) 7',0dh,0ah
- db ' 4) 11',0dh,0ah
- db ' 5) 12',0dh,0ah
- db ' 6) 15',0dh,0ah,'$'
-
- irqtbl db 2,3,5,7,11,12,15
-
- ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
- ; EXTRA CRAP CODE
- ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
-
- ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
- ; Find a GUS (environment variable)
- ; Out:
- ; EAX,ECX,ESI,EDI - ?
- ; CF=0 - found GUS
- ; CF=1 - no GUS found
- ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
- _gs_find:
- mov esi,_pspa
- movzx esi,word ptr gs:[esi+2ch]
- shl esi,4
- gsfindl3:
- mov edi,offset pspultrastr
- mov ecx,8
- repe cmps byte ptr gs:[esi],byte ptr es:[edi]
- jne short gsfindf0
- mov edi,10h
- call gsfindr0
- mov _gusport,cx
- call gsfindr0
- call gsfindr0
- mov edi,10
- call gsfindr0
- mov _gusirq,cl
- clc
- ret
- gsfindf0:
- lea esi,[esi+ecx-8]
- gsfindl0:
- inc esi
- cmp byte ptr gs:[esi-1],0
- jne gsfindl0
- cmp byte ptr gs:[esi],0
- jne gsfindl3
- stc
- ret
- ;-----------------------------------------------------------------------------
- gsfindr0:
- movzx eax,byte ptr gs:[esi]
- inc esi
- sub al,'0'
- jc gsfindr0
- cmp al,9
- ja gsfindr0
- mov ecx,eax
- gsfindr0l0:
- mov al,gs:[esi]
- inc esi
- sub al,'0'
- jc gsfindr0d
- cmp al,9
- ja gsfindr0d
- imul ecx,edi
- add ecx,eax
- jmp gsfindr0l0
- gsfindr0d:
- ret
-
- ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
- ; Ask if GUS present and for port and IRQ
- ; Out:
- ; EAX,EDX - ?
- ; CF=0 - no GUS
- ; CF=1 - GUS be here
- ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
- _gs_ask:
- mov byte ptr _gusport,20h
- mov _gusirq,11
- mov edx,offset askmsg0
- call _putdosmsg
- gsaskl1:
- call _getch
- cmp al,13
- je short gsaskd
- sub al,'0'
- jc gsaskl1
- je short gsaska
- cmp al,6
- ja gsaskl1
- shl al,4
- mov byte ptr _gusport,al
- mov edx,offset askmsg1
- call _putdosmsg
- gsaskl0:
- call _getch
- sub al,'0'
- jc gsaskl0
- cmp al,6
- ja gsaskl0
- movzx eax,al
- mov al,irqtbl[eax]
- mov _gusirq,al
- gsaskd:
- clc
- ret
- gsaska:
- stc
- ret
-
- ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
- ; Test _gusport
- ; Out:
- ; AX,BL,DX - ?
- ; CF=0 - GUS failed
- ; CF=1 - GUS passed
- ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
- _gs_test: ; Temporarily out of service
- clc
- ret
- ; mov ax,900h
- ; int 31h
- ; push ax
- ; mov dx,_gusport
- ; add dx,103h
- ; @outb 44h
- ; in al,dx
- ; cmp al,44h
- ; jne short gstesta
- ; add dl,2
- ; @outb 0
- ; sub dl,2
- ; @outb 43h
- ; inc edx
- ; @outw 0
- ; add dl,3
- ; in al,dx
- ; mov bl,al
- ; sub dl,3
- ; @outw 1
- ; add dl,3
- ; not bl
- ; @outb bl
- ; sub dl,3
- ; @outw 0
- ; add dl,3
- ; in al,dx
- ; cmp al,bl
- ; je short gstesta
- ; sub dl,3
- ; @outw 1
- ; add dl,3
- ; in al,dx
- ; cmp al,bl
- ; jne short gstesta
- ; clc
- ; pop ax
- ; int 31h
- ; ret
- gstesta:
- ; stc
- ; pop ax
- ; int 31h
- ; ret
- endif
-
- code32 ends
- end
-
-